package com.hw.job_2;

import java.util.Scanner;
import java.util.Arrays;

public class Gobang {

    // 定义二维数组，来描述当前棋盘，其中+代表空，O代表白字，@代表黑子
    private int length = 16;
    private String[][] pieces = new String[length][length];
    // 菜单
    String[] menu = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
            "a", "b", "c", "d", "e", "f"};

    // 定义黑白双方角色，true为黑子，false为白字
    private boolean blackSide = true;
    private String winSide = null;
    private int line_count = 1;

    public Gobang() {
        // 初始化棋盘
        for(int i = 0; i < pieces.length; i++) {
            for (int j = 0; j < pieces[i].length; j++) {
                pieces[i][j] = "+";
            }
        }
    }

    // 绘制棋盘
    public void printBoard() {

        // 数组越界判断
        if (pieces.length > menu.length) {
            System.out.println("棋子数组越界");
            return;
        }

        // 打印棋盘
        System.out.println("当前棋盘如下：");
        String rowSpace = "  ";
        for(int i = 0; i < menu.length+1; i++) {
            for(int j = 0; j < menu.length+1; j++) {
                if(i == 0 && j == 0) {
                    System.out.print(" ");
                } else if(i == 0) {
                    System.out.print(menu[j-1]);
                } else if(j == 0) {
                    System.out.print(menu[i-1]);
                } else {
                    System.out.print(pieces[i-1][j-1]);
                }
                System.out.print(rowSpace);
            }
            System.out.println();
        }
    }

    // 提示用户下棋
    public void playChess() {
        Scanner scan = new Scanner(System.in);
        System.out.println("轮到" + (isBlackSide() ? "黑色方" : "白色方") + "下棋，请输入：行 列");
        String row = scan.next();
        String col = scan.next();

        // 检查输入是否在合理范围
        if (!Arrays.asList(menu).contains(row) || !Arrays.asList(menu).contains(col)) {
            System.out.println("输入值不在合法范围，请检查后重新输入！！！");
            return;
        }

        // 将下的棋插入数组对应的位置
        String piece = isBlackSide() ? "@" : "O";
        int row_index = Arrays.asList(menu).indexOf(row);
        int col_index = Arrays.asList(menu).indexOf(col);
        // 判断此处是否下过棋
        if (!pieces[row_index][col_index].equals("+")) {
            System.out.println("此处已经下过棋，请检查后重新输入！！！");
            return;
        }
        pieces[row_index][col_index] = piece;
        judgeWin(isBlackSide(),row_index,col_index);

        // 交换下棋方
        setBlackSide(!isBlackSide());
        return;
    }

    // 判断是否获胜
    private void judgeWin(boolean blackSide, int row_index, int col_index) {

        String piece = blackSide ? "@" : "O";

        // 1. 同一行判断
        line_count = 1;
        // 左边行
        if (col_index > 0) {
            for (int col = col_index-1; col >= 0; col--) {
                if (!judgeLineCount(blackSide, row_index, col)) { break; };
                if (line_count == 5) return;
            }
        }
        // 右边行
        if (col_index < length-1) {
            for (int col = col_index+1; col <= length-1; col++) {
                if (!judgeLineCount(blackSide, row_index, col)) { break; };
                if (line_count == 5) return;
            }
        }

        // 2. 同一列判断
        line_count = 1;
        // 上边列
        if (row_index > 0) {
            for (int row = row_index-1; row >= 0; row--) {
                if (!judgeLineCount(blackSide, row, col_index)) { break; };
                if (line_count == 5) return;
            }
        }
        // 下边列
        if (row_index < length-1) {
            for (int row = row_index+1; row <= length-1; row++) {
                if (!judgeLineCount(blackSide, row, col_index)) { break; };
                if (line_count == 5) return;
            }
        }

        // 3. 左上-右下判断
        line_count = 1;
        int lurd_row = row_index-1;
        int lurd_col = col_index-1;
        while (lurd_row >= 0 && lurd_col >= 0) {
            if (!judgeLineCount(blackSide, lurd_row, lurd_col)) { break; }
            if (line_count == 5) return;
            lurd_row--;
            lurd_col--;
        }
        lurd_row = row_index+1;
        lurd_col = col_index+1;
        while (lurd_row <= length-1 && lurd_col <= length-1) {
            if (!judgeLineCount(blackSide, lurd_row, lurd_col)) { break; }
            if (line_count == 5) return;
            lurd_row++;
            lurd_col++;
        }

        // 4. 左下-右上判断
        line_count = 1;
        int ldru_row = row_index+1;
        int ldru_col = col_index-1;
        while (ldru_row <= length-1 && ldru_col >= 0) {
            if (!judgeLineCount(blackSide, ldru_row, ldru_col)) { break; }
            if (line_count == 5) return;
            ldru_row++;
            ldru_col--;
        }
        ldru_row = row_index-1;
        ldru_col = col_index+1;
        while (ldru_row >= 0 && ldru_col <= length-1) {
            if (!judgeLineCount(blackSide, ldru_row, ldru_col)) { break; }
            if (line_count == 5) return;
            ldru_row--;
            ldru_col++;
        }
    }

    // 返回true，表示应继续循环，false停止循环
    private boolean judgeLineCount(boolean blackSide, int row_index, int col_index) {
        String piece = blackSide ? "@" : "O";
        if (pieces[row_index][col_index].equals(piece)) {
            line_count++;
            if (line_count == 5) {
                winSide = blackSide ? "黑方": "白方";
                System.out.println("恭喜" + winSide + "获胜！！！");
            }
            return true;
        } else {
            // 若棋子不连续，则退出循环
            return false;
        }
    }

    // get&set方法
    public boolean isBlackSide() {
        return blackSide;
    }

    // 定义私有方法，不允许外面赋值
    private void setBlackSide(boolean blackSide) {
        this.blackSide = blackSide;
    }

    public String getWinSide() {
        return winSide;
    }

    private void setWinSide(String winSide) {
        this.winSide = winSide;
    }
}
